package com.fuchuang.seckillsystem.filter;

import com.fuchuang.seckillsystem.entity.MyUserDetails;
import com.fuchuang.seckillsystem.service.impl.UserDetailServiceImpl;
import com.fuchuang.seckillsystem.utils.JsonWebTokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * token拦截器
 */
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    
    @Autowired
    private JsonWebTokenUtils tokenUtil;
    @Autowired
    private UserDetailServiceImpl userDetailService;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //从请求头部获取json web token
        String token = request.getHeader(tokenUtil.getHeader());
        //判断是否不为空
        if (StringUtils.hasLength(token) && !token.equals("null") && !token.equals("undefined")) {
            //从token中获取用户名
            String username = tokenUtil.getUsernameFromToken(token);
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                //通过用户名查询
                MyUserDetails userDetails = (MyUserDetails) redisTemplate.opsForValue().get("userDetail:" + username);
                if (userDetails == null) {
                    userDetails = (MyUserDetails) userDetailService.loadUserByUsername(username);
                }
                if (tokenUtil.validateToken(token, userDetails)) {
                    //创建认证信息
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails,
                            userDetails.getPassword(), userDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    // 将 authentication 存入 ThreadLocal，方便后续获取用户信息
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        filterChain.doFilter(request, response);
    }
}

